# -*- encoding: utf-8 -*-

from odoo import models, fields, api
from odoo.addons import base_cw
from odoo.exceptions import UserError


class MoneyOrderWriteOff(models.Model):
    _name = 'money.order.write.off'
    _inherit = ['account.voucher.script']
    _description = '汇票冲销'

    name = fields.Char(string='名称')
    documents_type = fields.Selection(selection=[('pay', '付款单'), ('receive', u'收款单')], string='冲销单据', default='pay')

    @api.onchange('documents_type')
    def _onchange_documents_type(self):
        for record in self:
            if record.documents_type == 'pay':
                record.receive_id = False
                record.receive_line_id = False
            if record.documents_type == 'receive':
                record.payment_id = False
                record.payment_line_id = False
            record.money_order_id = False
            record.money_order_line_id = False

    pay_type = fields.Selection(selection=[('money_order', '汇票冲销'), ('cash', u'现金冲销')], string='支付类型',
                                default='money_order')

    @api.onchange('pay_type')
    def _onchange_pay_type(self):
        for record in self:
            if record.documents_type == 'cash':
                record.money_order_id = False
                record.money_order_line_id = False

    payment_id = fields.Many2one(comodel_name='account.pay', string='付款单')
    payment_line_id = fields.Many2one(comodel_name='account.pay.line', string='付款单明细')

    @api.onchange('payment_line_id')
    def _onchange_payment_line_id(self):
        for record in self:
            if record.payment_line_id:
                record.write_off_amount = record.payment_line_id.wait_write_off_amount

    receive_id = fields.Many2one(comodel_name='account.receive', string='收款单')
    receive_line_id = fields.Many2one(comodel_name='account.receive.line', string='收款单明细')

    @api.onchange('receive_line_id')
    def _onchange_receive_line_id(self):
        for record in self:
            if record.payment_line_id:
                record.write_off_amount = record.payment_line_id.wait_write_off_amount

    money_order_id = fields.Many2one(comodel_name='money.order', string='使用汇票')
    money_order_money = fields.Monetary(related='money_order_id.money_order_money', string='开票金额')
    money_order_line_id = fields.Many2one(comodel_name='money.order.line', string='汇票明细')
    voucher_id = fields.Many2one(comodel_name='account.voucher', string='冲销凭证', readonly=True, store=True)

    write_off_amount = fields.Monetary(string='冲销金额')
    partner_bank_id = fields.Many2one(comodel_name='res.partner.bank', string='出票银行')
    supplier_id = fields.Many2one(comodel_name='res.partner', string='供应商', related='payment_id.partner_id')
    customer_id = fields.Many2one(comodel_name='res.partner', string='客户', related='receive_id.partner_id')
    d_account_id = fields.Many2one(comodel_name='cncw.account', string='冲销借方科目')
    c_account_id = fields.Many2one(comodel_name='cncw.account', string='冲销贷方科目')
    comment = fields.Char(string='备注')
    script_line_ids = fields.One2many('account.voucher.script.line', 'money_order_write_off_id', u'预切凭证明细')
    company_id = fields.Many2one('res.company', string='公司', default=lambda self: self.env.company.id)
    currency_id = fields.Many2one(comodel_name='res.currency', string='币别',
                                  default=lambda self: self.env.user.company_id.currency_id)
    exchange_rate = fields.Float(u'汇率', digits='Exchange Rate', related='currency_id.rate')
    is_summary_generate_voucher = fields.Boolean(u'汇开凭证', default=False)

    def action_voucher_script_line(self):
        """
        生成预切明细
        :return:
        """
        for record in self:
            # 贷方
            d_items = []
            account_id = record.c_account_id
            dc_type = 'C'
            money = 0 - record.write_off_amount
            d_vals = dict(dc_type=dc_type,
                          account_id=account_id.id,
                          currency_id=record.currency_id.id,
                          exchange_rate=record.exchange_rate,
                          name='%s;%s' % ('汇票红字回冲', record.name),
                          money_order_write_off_id=record.id,
                          debit=0,
                          credit=money,
                          lc_debit=0,
                          lc_credit=money
                          )
            if record.supplier_id:
                sub_account_id = record.supplier_id
            else:
                sub_account_id = record.customer_id

            line_data = {'category_id': sub_account_id.subaccount_category_id.id,
                         'sub_account_id': sub_account_id.id or False}
            sub_account_lines_data = [(0, 0, line_data)]
            d_vals.update(dict(
                sub_account_id=sub_account_id.id,
                sub_account_lines=sub_account_lines_data
            ))
            d_items.append((0, 0, d_vals))

            # 借方
            c_items = []
            account_id = record.d_account_id
            dc_type = 'D'
            c_vals = dict(dc_type=dc_type,
                          account_id=account_id.id,
                          currency_id=record.currency_id.id,
                          exchange_rate=record.exchange_rate,
                          name='%s;%s' % ('汇票红字回冲', record.name),
                          money_order_write_off_id=record.id,
                          debit=money,
                          credit=0,
                          lc_debit=money,
                          lc_credit=0
                          )
            sub_account_id = record.company_id.partner_id
            line_data = {'category_id': sub_account_id.subaccount_category_id.id,
                         'sub_account_id': sub_account_id.id or False}
            sub_account_lines_data = [(0, 0, line_data)]
            c_vals.update(dict(
                sub_account_id=sub_account_id.id,
                sub_account_lines=sub_account_lines_data
            ))
            c_items.append((0, 0, c_vals))
            items = d_items + c_items
            record.write((dict(script_line_ids=items)))
            print('生成预切明细')

    def action_voucher_script_line_cancel(self):
        """
        取消预切明细
        :return:
        """
        for record in self:
            record.script_line_ids.unlink()

    def action_generate_voucher(self):
        """
        生成凭证
        :return:
        """
        for record in self:
            voucher_id = self.env['account.voucher'].create(dict(
                date=fields.Date.context_today(record),
                origin=record.name,
                voucher_category_id=self.env.ref('cncw_ledger.account_voucher_category_01').id
            ))
            sudo_script_lines = record.script_line_ids
            items = []
            for x in sudo_script_lines:
                sub_account_lines_data = []
                sub_account_ids = []
                for line in x.sub_account_lines:
                    sub_account_id = line.sub_account_id.id
                    if sub_account_id not in sub_account_ids:
                        sub_account_ids.append(sub_account_id)
                        line_data = {'category_id': line.category_id.id, 'sub_account_id': sub_account_id}
                        sub_account_lines_data.append((0, 0, line_data))

                item = dict(sequence=x.sequence,
                            dc_type=x.dc_type,
                            account_id=x.account_id.id,
                            sub_account_id=x.sub_account_id and x.sub_account_id.id or False,
                            name=x.name,
                            currency_id=x.currency_id and x.currency_id.id or False,
                            exchange_rate=x.exchange_rate,
                            debit=x.debit or False,
                            credit=x.credit or False,
                            lc_debit=x.lc_debit,
                            lc_credit=x.lc_credit,
                            sub_account_lines=sub_account_lines_data,
                            company_id=x.company_id and x.company_id.id or False,
                            move_ids=[(6, 0, x.move_ids.ids)]
                            )
                items.append((0, 0, item))
            # _logger.info("_________________凭证写入__________________%s" % items)
            voucher_id.write(dict(line_ids=items))
            sudo_script_lines.write(dict(voucher_id=voucher_id.id))
            if voucher_id.line_ids:
                record.voucher_id = voucher_id
            if record.money_order_id:
                # 创建汇票明细
                record.money_order_line_id = record.env['money.order.line'].create(dict(
                    drawer=record.supplier_id.id or record.company_id.id,
                    transfer_partner_id=record.company_id.partner_id.id,
                    partner_bank_id=record.partner_bank_id.id,
                    payee=record.supplier_id.id or record.company_id.id,
                    transfer_money=record.write_off_amount,
                    money_order_id=record.money_order_id.id,
                    payment_date=fields.date.today(),
                    payment_line_id=record.payment_line_id.id,
                    payment_id=record.payment_id.id,
                    reversal_voucher_id=record.voucher_id.id if record.voucher_id else False
                ))

    def action_voucher_cancel(self):
        """取消凭证"""
        for record in self:
            voucher_id = record.voucher_id
            record.voucher_id = False
            if voucher_id:
                voucher_id.action_cancel_confirm()
                voucher_id.action_cancel()
                voucher_id.unlink()


class AccountVoucherScriptLine(models.Model):
    _inherit = 'account.voucher.script.line'
    _description = u'预切凭证明细扩展'

    money_order_write_off_id = fields.Many2one(comodel_name='money.order.write.off')

    @api.model
    def create(self, vals):
        master_column = ''
        if vals.get('money_order_write_off_id', False):
            master_column = 'money_order_write_off_id'
        base_cw.public.generate_sequence(self, vals, master_column=master_column)
        return super(AccountVoucherScriptLine, self).create(vals)


class AccountPay(models.Model):
    _inherit = 'account.pay'
    _description = u'付款单'

    money_order_write_off_ids = fields.One2many(comodel_name='money.order.write.off', inverse_name='payment_id',
                                                string='汇票冲销')


class AccountPayLine(models.Model):
    _inherit = 'account.pay.line'
    _description = u'付款单明细'

    wait_write_off_amount = fields.Monetary(string='待冲销金额', currency_field='currency_id',
                                            compute='_compute_money_order_amount', store=True)
    remaining_write_off_amount = fields.Monetary(string='剩余冲销金额', redonly=True, store=True)

    @api.depends('money_order', 'amount')
    def _compute_money_order_amount(self):
        for record in self:
            if record.money_order and record.amount > 0:
                # 汇票金额 > 实际付款 需冲销汇票金额
                if record.money_order.money_order_money > record.amount:
                    # 待冲销金额 = 汇票金额 - 实际付款金额
                    record.wait_write_off_amount = record.money_order.money_order_money - record.amount
                    # 汇票金额 < 实际付款 提示
                elif record.money_order.money_order_money < record.amount:
                    raise UserError('金额输入错误，实际付款不可大于汇票金额')
                else:
                    record.wait_write_off_amount = 0
            else:
                record.wait_write_off_amount = 0
